﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EzDesk.Project.Model;
using EzDesk.Project.Service.Repositories;
using EzDesk.Project.Service.Repositories.Interfaces;
using EzDesk.EzAppApi.Utility;
using System.Diagnostics;
using EzDesk.EzAppApi.Utility.EzDeskAppApi;
using EzDesk.Project.Service.Repositories.Mock;
using EzDesk.Project.Model.ViewModel;

namespace EzDesk.Project.Service
{
    /// <summary>
    /// 项目相关服务
    /// </summary>
    public class ProjectService : IProjectService
    {
        #region [ 构造器 ]

        IEzApiClient _appApiClient;
        IProjectTypeRepository _projectTypeRepository;
        IPlaneTypeRepository _planeTypeRepository;
        IProjectTeamRepository _projectTeamRepository;
        IPlaneTaskRepository _planeTaskRepository;
        IProjectBasictInfoRepository _basicInfoRepository;
        IWorkItemRepository _workItemRepository;
        ITaskRepository _taskRepostiroy;
        ITaskDependencyRepository _taskDependencyRepository;

        public ProjectService(
            IEzApiClient appApiClient,
            IProjectTypeRepository projectTypeRepository,
            IPlaneTypeRepository planeTypeRepository,
            IProjectTeamRepository projectTeamRepository,
            IPlaneTaskRepository planeTaskRepository,
            IProjectBasictInfoRepository basicInfoRepository,
            IWorkItemRepository workItemRepository,
            ITaskRepository taskRepostiroy,
            ITaskDependencyRepository taskDependencyRepository
            )
        {
            this._appApiClient = appApiClient;
            this._projectTypeRepository = projectTypeRepository;
            this._planeTypeRepository = planeTypeRepository;
            this._projectTeamRepository = projectTeamRepository;
            this._planeTaskRepository = planeTaskRepository;
            this._basicInfoRepository = basicInfoRepository;
            this._workItemRepository = workItemRepository;
            this._taskRepostiroy = taskRepostiroy;
            this._taskDependencyRepository = taskDependencyRepository;
        }

        //todo: DI重构
        public ProjectService()
            : this(
                new EzApiClient(),
                new ProjectTypeRepository(),
                new Mock_PlaneTypeRepository(),
                new Mock_ProjectTeamRepository(),
                new Mock_PlaneTaskRepository(),
                new Mock_ProjectBasicInfoRepository(),
                new Mock_WorkItemRepository(),
                new Mock_TaskRepository(),
                new Mock_ProjectTaskDependency()
            )
        {
        }

        #endregion

        #region [ Project Types ]
        public IList<ProjectType> GetAllProjectTypes()
        {
            return _projectTypeRepository.GetAll().OrderBy(p => p.OrderNo).ToList();
        }
        #endregion

        #region [ PlaneTask Types ]

        public IList<PlaneType> GetAllPlaneTypes()
        {
            return _planeTypeRepository.GetAll().OrderBy(p => p.OrderNo).ToList();
        }
        #endregion

        #region [ Project BasicInfo ]


        // 创建一个新的项目
        public Guid CreateProject(ProjectBasicInfo newProject, ProjectTeam teamInfo, SimpleUser creator)
        {
            //todo: 处理创建项目的权限问题

            // 验证项目基本信息
            validateBasicInfo(newProject);

            // 验证项目团队
            validateProjectTeam(teamInfo);

            teamInfo.Id = Guid.NewGuid();
            Guid newTeamId = _projectTeamRepository.Add(teamInfo, true);
            newProject.ProjectTeamId = newTeamId;

            newProject.Id = Guid.NewGuid();

            newProject.CreateOn = DateTime.Now;
            // 创建项目基本信息
            _basicInfoRepository.Add(newProject, true);

            return newProject.Id;
        }

        // 直接获得公司所有项目
        public IList<ProjectBasicInfo> GetAllProjects()
        {
            return _basicInfoRepository.GetAll().ToList();
        }

        // 根据筛选条件获取项目列表
        public IList<ProjectBasicInfo> GetProjetList(bool? isClosed = false, string orderBy = "")
        {
            // todo: 对条件进行错误判断

            return _basicInfoRepository.GetProjectList(isClosed, orderBy);
        }

        // 获取项目基本信息
        public ProjectBasicInfo GetProjectBasicInfo(Guid projectId)
        {
            return _basicInfoRepository.GetById(projectId);
        }
        #endregion

        #region [ Project ViewModel ]

        // 获得一个项目的所有阶段任务
        public IList<ProjectViewModel> GetProjectForView(IList<ProjectBasicInfo> basicInfoList)
        {
            IList<ProjectViewModel> result = new List<ProjectViewModel>();

            foreach (var item in basicInfoList)
            {
                result.Add(new ProjectViewModel()
                {
                    BasicInfo = item,
                    PlaneTasks = getPlaneTasksForView(_planeTaskRepository.GetPlanesFromProject(item.Id)),
                });
            }

            return result;
        }

        #endregion

        #region [ Project Team ] 
        public ProjectTeam GetProjectTeam(ProjectBasicInfo projectBasicInfo)
        {
            if (projectBasicInfo == null || projectBasicInfo.Id == Guid.Empty)
            {
                throw new Exception("必须指定一个已存在的项目");
            }

            if (projectBasicInfo.ProjectTeamId == Guid.Empty)
            {
                throw new Exception("内部错误:项目未指定有效的团队");
            }

            return _projectTeamRepository.GetById(projectBasicInfo.ProjectTeamId);
        }


        public ProjectTeam GetProjectTeam(Guid teamId)
        {
            return _projectTeamRepository.GetById(teamId);
        }

        #endregion

        #region [ Project Planes]

        public PlaneTaskViewModel GetPlaneTaskForView(Guid planeTaskId)
        {
            return getPlaneTaskForView(_planeTaskRepository.GetById(planeTaskId));
        }


        public IList<PlaneTask> GetPlanesFromProject(Guid projectId)
        {
            return _planeTaskRepository.GetPlanesFromProject(projectId);
        }

        public Guid CreatePlaneTask(PlaneTask newPlaneTask)
        {
            return _planeTaskRepository.Add(newPlaneTask, true);
        }

        public PlaneTask GetPlaneTask(Guid planeTaskId)
        {
            return _planeTaskRepository.GetById(planeTaskId);
        }


        #endregion

        #region [ Project Tasks ]
        
        public IList<Task> GetChildTasks(Task parentTask)
        {
            IList<Task> childTasks = _taskRepostiroy.GetTasksByParentId(parentTask.Id);
            foreach (Task task in childTasks)
            {
                task.ChildTasks = GetChildTasks(task);
            }
            return childTasks;
        }
        
        #endregion






















        public IList<ProjectBasicInfo> GetOpenProjects(Guid CurrentUserId)
        {
            return _basicInfoRepository.GetAll().ToList();
        }

        public ProjectBasicInfo GetBasicInfo(Guid projectId)
        {
            return _basicInfoRepository.GetById(projectId);
        }

        public void RemoveProject(Guid newProjectId)
        {
            // 完整移除一个Project

            // 移除项目基本信息
            _basicInfoRepository.Delete(newProjectId, true);
        }

        public void UpdateBasicInfo(ProjectBasicInfo projectInfo)
        {
            // 更新项目基本信息
            throw new NotImplementedException();
        }


        #region [ Project Team ]
        // 创建一个项目的项目团队
        //public void CreateProjectTeam(BasicInfo project, ProjectTeam team)
        //{
        //    validateProjectTeam(team);

        //    // team合法性判断
        //    if (team.ProjectId != project.Id)
        //    {
        //        throw new Exception("项目ID不可用");
        //    }

        //    // 获得现有的项目团队
        //    var currentProjectTeam = GetProjectTeam(project);
        //    if (currentProjectTeam != null)
        //    {
        //        throw new Exception("项目已经有一个团队了");
        //    }
                       
        //    //var newTeam = _projectTeamService.GetTeamById(team.Id);
        //    //if (currentProjectTeam != null)
        //    //{
        //    //    throw new Exception("团队ID已经存在！");
        //    //}

        //    //// 添加新的团队
        //    //_projectTeamService.AddTeam(team);

        //    project.ProjectTeamId = team.Id;
        //    _projectRepository.Update(project, true);
        //}
        
        //// 获得项目的现有项目团队,没有团队返回null
        //public ProjectTeam GetProjectTeam(BasicInfo project)
        //{
        //    ProjectTeam team = null;
        //    if (project.ProjectTeamId != null)
        //    {
        //        team = _projectTeamService.GetTeamById(project.ProjectTeamId);
        //    }
        //    return team;
        //}
        #endregion


        #region [ private methods ]

        private IList<PlaneTaskViewModel> getPlaneTasksForView(IList<PlaneTask> planes)
        {
            IList<PlaneTaskViewModel> result = new List<PlaneTaskViewModel>();

            foreach (var item in planes)
            {
                result.Add(getPlaneTaskForView(item));
            }

            return result;
        }

        private PlaneTaskViewModel getPlaneTaskForView(PlaneTask planes)
        {
            return new PlaneTaskViewModel()
            {
                BaseModel = planes,
                State = getStateInTask(planes),
            };
        }

        private TaskStateEnum getStateInTask(Task task)
        {
            TaskStateEnum result = TaskStateEnum.已完成;

            DateTime now = DateTime.Now;
            if (!task.IsClosed)
            {
                // 如果被关闭，则直接标注已完成,未关闭状态下根据时间判断
                if (now < task.StartOn)
                {
                    result = TaskStateEnum.未开始;
                }
                else
                {
                    result = TaskStateEnum.进行中;
                }
            }
            return result;
        }

        // 验证一个ProjectTeam的合法性
        private void validateBasicInfo(ProjectBasicInfo theProject)
        {
            // 检测非空
            if (string.IsNullOrEmpty(theProject.ProjectName))
            {
                throw new Exception("项目名称不能为空");
            }
            if (string.IsNullOrEmpty(theProject.ProjectNo))
            {
                throw new Exception("项目编号不能为空");
            }

            // Project No., Name不允许重复
            var allProjects = _basicInfoRepository.GetAll();
            if (allProjects.Where(p => p.ProjectNo == theProject.ProjectNo).Count() > 0)
            {
                throw new Exception("项目编号已存在");
            }
            if (allProjects.Where(p => p.ProjectName == theProject.ProjectName).Count() > 0)
            {
                throw new Exception("项目名称已存在");
            }
        }

        // 验证一个ProjectTeam的合法性
        private void validateProjectTeam(ProjectTeam team)
        {
            if (team == null)
            {
                throw new Exception("必须指定项目团队");
            }

            if (team.Members == null || team.Members.Count == 0)
            {
                throw new Exception("必须指定项目团队");
            }

            // team manager必须存在
            if (team.Manager == null)
            {
                throw new Exception("必须指定项目经理");
            }
            // team Manager必须为members中一员

            // todo: 重构 override Contains方法
            bool managerIsInTeam = false;
            foreach(var member in team.Members)
            {
                if (member.Id == team.Manager.Id)
                {
                    managerIsInTeam = true;
                    break;
                }
            }
            if (!managerIsInTeam)
            {
                throw new Exception("项目经理必须为项目团队成员");
            }
        }
        #endregion
















    }
}
